/*
 * Author: vdaras
 */

#include "AbstractButton.h"

#include "../sdl/sdl_utilities.h"
#include "../MouseEvent.h"

namespace gui
{

AbstractButton::AbstractButton(const std::string &name, int width, int height)
:
Component(name, width, height),
m_currentDisplay(REGULAR)
{
}


AbstractButton::AbstractButton(const std::string& name, Container* parent, int x, int y, int width, int height)
:
Component(name, parent, x, y, width, height),
m_currentDisplay(REGULAR)
{
}

AbstractButton::~AbstractButton()
{
}


/**
 * This routine returns whether the mouse cursor's coordinates are inside the
 * area of the Button.
 *
 * @param mouseX: x coordinate of the mouse cursor
 * @param mouseY: y coordinate of the mouse cursor
 * @return true if cursor is inside the button, otherwise false
 */

bool AbstractButton::CursorInArea(int mouseX, int mouseY)
{
    SDL_Rect absVisibleRect = GetVisibleRect( );
    
    return sdl::PointInRect( mouseX, mouseY, &absVisibleRect );
}


/**
 * This routine notifies each Action Listener that an action was performed to this
 * Button.
 */

void AbstractButton::FireActionEvent()
{
    //for each Action Listener
    std::list< ActionListener* >::iterator iter(m_listeners.begin()), end(m_listeners.end());

    for(; iter != end; ++iter)
    {
        //notify
        (*iter)->ActionPerformed(this);
    }
}



/**
 * Handles a mouse event occurred.
 *
 * @param event: the event.
 */

void AbstractButton::OnMouseEvent(MouseEvent& event)
{
    if( event.GetType( ) == MOUSE_MOTION )
    {
	if( !m_clicked )
	{
	    int mouseX, mouseY;
	    
	    event.GetOccurredCoordinates( &mouseX, &mouseY );
	    
	    if( !event.IsConsumed( ) )
	    {
		if( CursorInArea( mouseX, mouseY ) )
		{
		    m_currentDisplay = HIGHLIGHTED;
		    
		    event.Consume( );
		}
		else
		{
		    m_currentDisplay = REGULAR;
		}
	    }
	    else
	    {
		m_currentDisplay = REGULAR;
	    }
	
	}
    }
    if( event.GetType( ) == MOUSE_CLICKED )
    {
	//if this mouse event reached this button, then it has focus and it's clicked
	m_currentDisplay = CLICKED;
	
	m_clicked = true;
    }
    else if( event.GetType( ) == MOUSE_RELEASED )
    {
        int mouseX, mouseY;
	
	event.GetOccurredCoordinates( &mouseX, &mouseY );
	
        if( CursorInArea( mouseX, mouseY ) )
	{
	    m_currentDisplay = HIGHLIGHTED;
	}
	else
	{
	    m_currentDisplay = REGULAR;
	}
	
	FireActionEvent( );
	
	m_clicked = false;
    }
}

};
